﻿/*****************************************介绍*****************************************
 * 作者：User
 * 创建时间：2025-06-09 13:55:50
 * 功能：广告基类
**************************************************************************************/

using Game.Framework;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class AdBase
{
    protected readonly string m_AdUnitId;
    protected int m_RetryAttempt;
    protected ETriggerAdType m_TriggerType;
    protected double m_TotalReward;     // 当前总收益
    protected EAdType m_AdType;

    public AdBase(string adUnitId)
    {
        m_AdUnitId = adUnitId;
    }

    public abstract void Initialize();

    protected virtual void LoadAd()
    {
        var data = new Dictionary<string, object>
        {
            {"ad_type",m_AdType.ToString() },
            {"PlacementId","" },
            {"NetworkFirmId","" },
        };
        NativeInteraction.Instance.SendBILog("ad_request", data);
    }

    private IEnumerator RetryDelay(float delay)
    {
        LogManager.Log($"广告加载失败 type:{m_AdType}，等待{delay}秒后重新加载!!", "广告");
        yield return new WaitForSeconds(delay);
        LoadAd();
    }

    private string GetSceneName(ETriggerAdType type) => type switch
    {
        ETriggerAdType.AppOpen => "open",
        ETriggerAdType.Additional => "additional",
        ETriggerAdType.Inter => "inter",
        ETriggerAdType.Shuffle => "shuffle",
        ETriggerAdType.Hint => "hint",
        ETriggerAdType.Bomb => "bomb",
        ETriggerAdType.AddTime => "add_time",
        ETriggerAdType.Revival => "revival",
        ETriggerAdType.LevelWinGetCoin => "levelWinGetCoin",
        ETriggerAdType.DownloadImg => "downloadImg",
        ETriggerAdType.RestartLevel => "restart",
        ETriggerAdType.SelectIcon => "selectIcon",
        ETriggerAdType.RefreshIcon => "refreshIcon",
        _ => ""
    };

    // 广告已经准备好时调用
    protected virtual void OnLoadedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
    {
        m_RetryAttempt = 0;
        var data = new Dictionary<string, object>
        {
            {"ad_type",m_AdType.ToString() },
            {"PlacementId",adInfo.NetworkPlacement },
            {"NetworkFirmId",adInfo.NetworkName },
        };
        NativeInteraction.Instance.SendBILog("ad_inventory", data);
        LogManager.Log($"Max广告已准备就绪，type:{m_AdType} revenue:{adInfo.Revenue}，现在可以调用Show来显示广告", "广告");
    }

    // 广告加载失败时调用
    protected virtual void OnLoadFailedEvent(string adUnitId, MaxSdkBase.ErrorInfo errorInfo)
    {
        m_RetryAttempt++;
        double retryDelay = Math.Pow(2, Math.Min(6, m_RetryAttempt));
        CommonMono.Instance.StartCoroutine(RetryDelay((float)retryDelay));
        LogManager.Log($"无法加载Max广告，type:{m_AdType}，这里重试，retryAttempt:{m_RetryAttempt}", "广告");
    }

    // 广告显示成功时调用
    protected virtual void OnDisplayedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
    {
        EventCenter.Instance.Trigger(GameEventName.ON_SHOW_SUCCESS_AD, m_AdType, m_TriggerType);
        LogManager.Log($"Max广告成功显示，type:{m_AdType}，adUnitId:{adUnitId} revenue:{adInfo.Revenue}", "广告");
    }

    // 广告显示失败时调用
    protected virtual void OnAdFailedToDisplayEvent(string adUnitId, MaxSdkBase.ErrorInfo errorInfo, MaxSdkBase.AdInfo adInfo)
    {
        LoadAd();
        EventCenter.Instance.Trigger(GameEventName.ON_SHOW_FAILED_AD, m_AdType, m_TriggerType);
        m_TriggerType = ETriggerAdType.None;
        GameDataMgr.Instance.TriggerAdType = ETriggerAdType.None;
        LogManager.Log($"Max广告显示失败，type:{m_AdType}，adUnitId:{adUnitId} code:{errorInfo.Code} networkErrorCode{errorInfo.MediatedNetworkErrorCode} msg:{errorInfo.MediatedNetworkErrorMessage} info:{errorInfo.AdLoadFailureInfo}", "广告");
    }

    // 广告被点击时调用
    protected virtual void OnClickedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
    {
        var data = new Dictionary<string, object>
        {
            {"ad_type",m_AdType.ToString() },
            {"PlacementId",adInfo.NetworkPlacement },
            {"NetworkFirmId",adInfo.NetworkName },
        };
        NativeInteraction.Instance.SendBILog("ad_click", data);
        LogManager.Log($"OnClickAd，type:{m_AdType}， adUnitId:{adUnitId} revenue:{adInfo.Revenue}", "广告");
    }

    // 广告关闭时调用
    protected virtual void OnHiddenEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
    {
        LoadAd();
        EventCenter.Instance.Trigger(GameEventName.ON_CLOSE_AD, m_AdType, m_TriggerType);
        m_TriggerType = ETriggerAdType.None;
        GameDataMgr.Instance.TriggerAdType = ETriggerAdType.None;
        LogManager.Log($"关闭Max广告，type:{m_AdType}，预加载下一个广告， adUnitId:{adUnitId} revenue:{adInfo.Revenue}", "广告");
    }

    // 使用这个回调来跟踪用户收益
    protected virtual void OnAdRevenuePaidEvent(string adUnitId, MaxSdkBase.AdInfo info)
    {
        LogManager.Log($"广告收益计算前 type:{m_AdType} adUnitId:{adUnitId} revenue:{info.Revenue} total:{m_TotalReward}", "广告");

        #region 千次收益

        double value = 0;
        if (info.Revenue != -1)
            value = info.Revenue * 1000;
        string scene = GetSceneName(m_TriggerType);
        if (string.IsNullOrEmpty(scene)) return;
        var data = new Dictionary<string, object>
        {
            {"ad_type",m_AdType.ToString() },
            {"Ecpm",value },
            {"Revenue",info.Revenue },
            {"Currency","USD" },
            {"scene",scene },
            {"PlacementId",info.NetworkPlacement },
            {"NetworkFirmId",info.NetworkName },
        };
        NativeInteraction.Instance.SendBILog("ad_imp", data);

        #endregion

        #region H5上报

        var page = new Dictionary<string, object>
        {
            { "revenue", info.Revenue }
        };
        NativeInteraction.Instance.ReportToH5(JsonConvert.SerializeObject(page, Formatting.None));

        #endregion

        #region AF上报

        if (info.Revenue > 0) m_TotalReward += info.Revenue;
        if (m_TotalReward >= 0.1)
        {
            NativeInteraction.Instance.AFUploadAd("af_ad_revenue", m_TotalReward);
            NativeInteraction.Instance.AFUploadAd("af_new_ad_revenue", m_TotalReward * .5f);
            m_TotalReward = 0;
        }

        double realRevenue = info.Revenue * BaseDataMgr.Instance.Cfg.dot.mmp_ra;
        NativeInteraction.Instance.AFUploadAd("af_imp_revenue", realRevenue);

        #endregion

        LogManager.Log($"广告收益计算后 type:{m_AdType} adUnitId:{adUnitId} revenue:{info.Revenue} total:{m_TotalReward} half:{m_TotalReward * .5f} real:{realRevenue}");
    }

    /// <summary>显示广告</summary>
    public abstract void Show(ETriggerAdType type);
}